package com.air.ota.vo;

import com.air.common.util.CommonUtil;
import com.air.ota.util.ConfigProperties;
import com.air.ota.util.HexStringUtil;
import com.air.ota.util.HsmjUtil;
import com.air.ota.util.PBOCUtil;
import com.air.ota.util.PkgUtil;

public class UTKBaseDownlinkVO {
	
	
	
	protected byte   udhl;
	protected byte   ieia;
	protected byte   ieidla;
	protected byte[] cpl;
	protected byte   chl;
	protected byte[] spi;
	protected byte   kic;
	protected byte   kid;
	protected byte[] tar;
	protected byte[] cntr;
	protected byte   pcntr;
	
	
	protected byte   cmdType;
	protected byte   cmdVer;
	protected byte[] cmdLength;
	protected byte[] cmdData;
	protected byte[] encCmdData;
	
	protected byte[] random;
	protected byte[] mac;
	
	protected byte[] UTKSessionKey; 
	protected byte[] cardSequence;
	
	protected byte[] pkgSequence;
	
	public UTKBaseDownlinkVO(byte[] cardSequence,byte[] pkgSequence){
		this.udhl =0x02;
		this.ieia = 0x70;
		this.ieidla = 0x00;
		this.cpl = new byte[2];
		this.chl = (byte)0x0D;
		this.spi = HexStringUtil.hexStringToBytes("0000");
		this.kic = 0x00;
		this.kid = 0x00;
		this.tar = HexStringUtil.hexStringToBytes("09008F");
		this.cntr = HexStringUtil.hexStringToBytes("0000000000");
		this.pcntr = 0x00;
		
		this.cmdVer = 0x01;
		
		this.cardSequence = cardSequence;
		
		this.random =CommonUtil.randomString(4).getBytes();
		this.mac =new byte[4];
		
		//this.pkgSequence = PkgUtil.getNextPkgSequence();
		this.pkgSequence = pkgSequence;
		
	}
	
	public void setCmdType(byte cmdType){
		this.cmdType = cmdType;
	}
	
	public void setCmdData(byte[] cmdData){
		this.cmdData = cmdData;
	}
	
	private void encpyCmdData(){
		PBOCUtil pbocUtil = new PBOCUtil();
		UTKSessionKey = pbocUtil.buildUTKSessionKey(cardSequence, random);
		String filledCmdDataString=HexStringUtil.bytesToHexString(cmdData)+"80";
		int fillCount=8-(filledCmdDataString.length()/2)%8;
		for(int i=0;i<fillCount;i++){
			filledCmdDataString += "00";
		}
		//System.out.println("cmdData="+HexStringUtil.bytesToHexString(cmdData));
		//System.out.println("filledCmdData="+filledCmdDataString);
		
		//使用本地软件加密
		//this.encCmdData = pbocUtil.TripleDes(UTKSessionKey, HexStringUtil.hexStringToBytes(filledCmdDataString), 1);
		
		//使用加密机加密
		this.encCmdData = HsmjUtil.encrypt(cardSequence, random, HexStringUtil.hexStringToBytes(filledCmdDataString));
	}
	private void makeCPLLength(){
		String hexString=Integer.toHexString(18+encCmdData.length+8);
		int fillCount = 4-hexString.length();
		for(int i=0;i<fillCount;i++){
			hexString = "0"+hexString;
		}
		this.cpl = HexStringUtil.hexStringToBytes(hexString);
	}
	private void makeCmdLength(){
		String hexString=Integer.toHexString(encCmdData.length+8);
		int fillCount = 4-hexString.length();
		for(int i=0;i<fillCount;i++){
			hexString = "0"+hexString;
		}
		this.cmdLength = HexStringUtil.hexStringToBytes(hexString);
	}
	private void makeMac(){
		PBOCUtil pbocUtil = new PBOCUtil();
		byte[] toMacData = HexStringUtil.hexStringToBytes(
						   HexStringUtil.byteToHexString(this.cmdType)+
						   HexStringUtil.byteToHexString(this.cmdVer)+
						   HexStringUtil.bytesToHexString(this.cmdLength)+
						   HexStringUtil.bytesToHexString(this.encCmdData)+
						   HexStringUtil.bytesToHexString(this.random));
						   
		this.mac=pbocUtil.Mac(this.UTKSessionKey,toMacData, HexStringUtil.hexStringToBytes("0000000000000000"));
		
		
	}
	
	public byte[] buildPkg(){
		
		encpyCmdData();
		makeCmdLength();
		makeCPLLength();
		makeMac();

		
		String pkgHexString=HexStringUtil.byteToHexString(this.udhl)+
		HexStringUtil.byteToHexString(this.ieia)+
		HexStringUtil.byteToHexString(this.ieidla)+
		HexStringUtil.bytesToHexString(this.cpl)+
		HexStringUtil.byteToHexString(this.chl)+
		HexStringUtil.bytesToHexString(this.spi)+
		HexStringUtil.byteToHexString(this.kic)+
		HexStringUtil.byteToHexString(this.kid)+
		HexStringUtil.bytesToHexString(this.tar)+
		HexStringUtil.bytesToHexString(this.cntr)+
		HexStringUtil.byteToHexString(this.pcntr)+
		HexStringUtil.byteToHexString(this.cmdType)+
		HexStringUtil.byteToHexString(this.cmdVer)+
		HexStringUtil.bytesToHexString(this.cmdLength)+
		HexStringUtil.bytesToHexString(this.encCmdData)+
		HexStringUtil.bytesToHexString(this.random)+
		HexStringUtil.bytesToHexString(this.mac);
		
		pringCmdDataHexString();
		return HexStringUtil.hexStringToBytes(pkgHexString);
	}
	
	public byte[] getPkgSequence(){
		return this.pkgSequence;
	}
	
	public void pringCmdDataHexString(){
		System.out.println("Downlink Decrypted CmdHexString="+HexStringUtil.bytesToHexString(this.cmdData));
	}
	
	public static UTKBaseDownlinkVO updatePkgSequence(byte[] cardSequence,byte[] pkgSequence,String content){
		UTKBaseDownlinkVO downlinkVO = new UTKBaseDownlinkVO(cardSequence,pkgSequence);
		byte[] oldEncCmdData = HexStringUtil.hexStringToBytes(content.substring(46, content.length()-16));
		byte[] random = HexStringUtil.hexStringToBytes(content.substring(content.length()-16,content.length()-8));
		byte   cmdType=HexStringUtil.hexStringToBytes(content)[19];
		
		/*PBOCUtil pbocUtil = new PBOCUtil();
		byte[] UTKSessionKey = pbocUtil.buildUTKSessionKey(cardSequence, random);
		String oldCmdDataStrTmp = HexStringUtil.bytesToHexString(pbocUtil.TripleDes(UTKSessionKey, oldEncCmdData, 0));*/
		
		String oldCmdDataStrTmp = HexStringUtil.bytesToHexString(HsmjUtil.decrypt(cardSequence, random, oldEncCmdData));
		
		byte[] oldCmdData = HexStringUtil.hexStringToBytes(oldCmdDataStrTmp.substring(0,oldCmdDataStrTmp.lastIndexOf("80")));
		System.out.println("Old cmdData="+HexStringUtil.bytesToHexString(oldCmdData));
		
		byte[] newCmdData = oldCmdData;
		
		System.arraycopy(pkgSequence, 0, oldCmdData, newCmdData.length-4, 4);
		
		
		System.out.println("New cmdData="+HexStringUtil.bytesToHexString(newCmdData));
		
		
		downlinkVO.setCmdData(newCmdData);
		downlinkVO.setCmdType(cmdType);
		return downlinkVO;
	}
	
	
	
	public static void decrpytDownlinkSMS(String contentString,byte[] cardSequence){
		byte[] content = HexStringUtil.hexStringToBytes(contentString);
		int encCmdDataLength = content.length-23-8;
		byte[] encCmdData = new byte[encCmdDataLength];
		System.arraycopy(content, 23, encCmdData, 0, encCmdDataLength);
		
		byte[] random = new byte[4];
		int randomStartPos = content.length-8;
		System.arraycopy(content, randomStartPos, random, 0, 4);
		
		//PBOCUtil pbocUtil = new PBOCUtil();
		//byte[] UTKSessionKey = pbocUtil.buildUTKSessionKey(cardSequence, random);
		//String tmpCmdDataStr = HexStringUtil.bytesToHexString(pbocUtil.TripleDes(UTKSessionKey, encCmdData, 0));
		
		String tmpCmdDataStr = HexStringUtil.bytesToHexString(HsmjUtil.decrypt(cardSequence, random, encCmdData));
		
		
		String cmdData = tmpCmdDataStr.substring(0,tmpCmdDataStr.lastIndexOf("80"));
		
		System.out.println("Downlink Decrypted CmdHexString="+cmdData);
	}
	
}
